package org.jspresso.development;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.jspresso.framework.application.startup.development.AbstractTestDataPersister;
import org.jspresso.model.ActionTestInput;
import org.jspresso.model.ActionTestOutput;
import org.jspresso.model.Address;
import org.jspresso.model.BackActionTest;
import org.jspresso.model.GpsLocation;
import org.jspresso.model.Node;
import org.jspresso.model.Segment;
import org.jspresso.model.TestEntity;
import org.jspresso.model.TestScope;
import org.jspresso.model.Voyage;
import org.jspresso.tester.utils.TestEntitySerializer;
import org.springframework.beans.factory.BeanFactory;

/**
 * Persists some test data for the application.
 */
public class TestDataPersister extends AbstractTestDataPersister {

	/**
	 * Constructs a new <code>TestDataPersister</code> instance.
	 * 
	 * @param beanFactory
	 *            the spring bean factory to use.
	 */
	public TestDataPersister(BeanFactory beanFactory) {
		super(beanFactory);
	}

	/**
	 * Creates some test data using the passed in Spring application context.
	 */
	@Override
	public void createAndPersistTestData() {

		// Create some entities...
		GpsLocation location1 = createComponentInstance(GpsLocation.class); 
		location1.setLatitude(10);
		location1.setLongitude(20);
		
		GpsLocation location2 = createComponentInstance(GpsLocation.class); 
		location2.setLatitude(10);
		location2.setLongitude(20);
		
		GpsLocation location3 = createComponentInstance(GpsLocation.class); 
		location3.setLatitude(10);
		location3.setLongitude(20);
		
		Address adress1 = createComponentInstance(Address.class);  
		adress1.setNumber("1");
		adress1.setStreet("street 1");
		adress1.setGpsLocation(location1);
		
		Address adress2 = createComponentInstance(Address.class);  
		adress2.setNumber("2");
		adress2.setStreet("street 2");
		adress2.setGpsLocation(location2);

		
		Address adress3 = createComponentInstance(Address.class);  
		adress3.setNumber("3");
		adress3.setStreet("street 3");
		adress3.setGpsLocation(location3);

		Node paris = createEntityInstance(Node.class);
		paris.setName("Paris");
		paris.setAddress(adress1);
		saveOrUpdate(paris);

		Node dakar = createEntityInstance(Node.class);
		dakar.setName("Dakar");
		dakar.setAddress(adress2);
		saveOrUpdate(dakar);

		Node londre = createEntityInstance(Node.class);
		londre.setName("Londre");
		londre.setAddress(adress3);
		saveOrUpdate(londre);

		Segment parisDakar = createEntityInstance(Segment.class);
		parisDakar.setDeparture(paris);
		parisDakar.setArrival(dakar);
		saveOrUpdate(parisDakar);

		Segment londreParis = createEntityInstance(Segment.class);
		londreParis.setDeparture(londre);
		londreParis.setArrival(paris);
		saveOrUpdate(londreParis);
		
		Segment dakarLondre = createEntityInstance(Segment.class);
		dakarLondre.setDeparture(dakar);
		dakarLondre.setArrival(londre);
		saveOrUpdate(dakarLondre);
		TestEntitySerializer.serializeToStore(dakarLondre, null, false, false, getBackendController());


		Voyage voyage = createEntityInstance(Voyage.class);
		voyage.addToSegments(londreParis);
		voyage.addToSegments(parisDakar);
		voyage.setCreatedTimestamp(new Date());
		voyage.setRef("Voyage n°1");
		voyage.setDestination(dakar);
		saveOrUpdate(voyage);
		
		Voyage voyage2 = createEntityInstance(Voyage.class);
		voyage2.addToSegments(londreParis);
		voyage2.addToSegments(parisDakar);
		voyage2.setCreatedTimestamp(new Date());
		voyage2.setRef("Voyage n°2");
		voyage.setDestination(dakar);
		saveOrUpdate(voyage2);
		
		TestEntitySerializer.serializeToStore(voyage, null, false, false, getBackendController());
		TestEntitySerializer.serializeToStore(voyage2, null, false, false, getBackendController());

		
		BackActionTest backActionTest1 = createEntityInstance(BackActionTest.class);
		backActionTest1.setBackendBeanName("sample1BackAction");
		backActionTest1.setDescription("My first backend test");
		
		
		List<ActionTestInput> inputs = new ArrayList<ActionTestInput>();
		ActionTestInput input = createEntityInstance(ActionTestInput.class);
		input.setDescription("Input parameter : Voyage");
		input.setIoType(ActionTestInput.IO_TYPE_ACTION_PARAMETER);
		input.setParameterType(ActionTestInput.PARAMETER_TYPE_REF);
		input.setParameterRefValue(TestEntitySerializer.findTestEntity(voyage.getId(), Voyage.class, null, getBackendController()));
		inputs.add(input);
		saveOrUpdate(input);
		
		List<ActionTestOutput> outputs = new ArrayList<ActionTestOutput>();
		ActionTestOutput output = createEntityInstance(ActionTestOutput.class);
		output.setDescription("Output parameter : Voyage");
		output.setIoType(ActionTestInput.IO_TYPE_ACTION_PARAMETER);
		output.setParameterType(ActionTestInput.PARAMETER_TYPE_REF);
		output.setParameterRefValue(TestEntitySerializer.findTestEntity(voyage2.getId(), Voyage.class, null, getBackendController()));
		outputs.add(output);
		saveOrUpdate(output);
		
		
		backActionTest1.setInputs(inputs);
		backActionTest1.setOutputs(outputs);
		
		BackActionTest backActionTest2 = createEntityInstance(BackActionTest.class);
		backActionTest2.setBackendBeanName("sample2BackAction");
		backActionTest2.setDescription("My list backend test");
		
		List<ActionTestInput> inputs2 = new ArrayList<ActionTestInput>();
		ActionTestInput input2 = createEntityInstance(ActionTestInput.class);
		input2.setDescription("Input parameter : Voyage");
		input2.setIoType(ActionTestInput.IO_TYPE_ACTION_PARAMETER);
		input2.setParameterType(ActionTestInput.PARAMETER_TYPE_REF);
		input2.setParameterRefValue(TestEntitySerializer.findTestEntity(voyage.getId(), Voyage.class, null, getBackendController()));
		inputs2.add(input2);
		saveOrUpdate(input2);

		
		ActionTestInput input3 = createEntityInstance(ActionTestInput.class);
		input3.setDescription("Input parameter : Segment");
		input3.setIoType(ActionTestInput.IO_TYPE_CONTEXT);
		input3.setParameterKey("SEGMENT_TO_ADD");
		input3.setParameterType(ActionTestInput.PARAMETER_TYPE_REF);
		input3.setParameterRefValue(TestEntitySerializer.findTestEntity(dakarLondre.getId(), Segment.class, null, getBackendController()));
		inputs2.add(input3);
		saveOrUpdate(input3);
		
		List<ActionTestOutput> outputs2 = new ArrayList<ActionTestOutput>();
		ActionTestOutput output2 = createEntityInstance(ActionTestOutput.class);
		output2.setDescription("Output parameter : Segment list");
		output2.setIoType(ActionTestInput.IO_TYPE_ACTION_PARAMETER);
		output2.setParameterType(ActionTestInput.PARAMETER_TYPE_LIST);
		ArrayList<TestEntity> parameterOutRefValues = new ArrayList<TestEntity>();
		parameterOutRefValues.add(TestEntitySerializer.findTestEntity(londreParis.getId(), Segment.class, null, getBackendController()));
		parameterOutRefValues.add(TestEntitySerializer.findTestEntity(parisDakar.getId(), Segment.class, null, getBackendController()));
		parameterOutRefValues.add(TestEntitySerializer.findTestEntity(dakarLondre.getId(), Segment.class, null, getBackendController()));
		output2.setParameterRefValues(parameterOutRefValues);
		outputs2.add(output2);
		saveOrUpdate(output2);
		
		backActionTest2.setInputs(inputs2);
		backActionTest2.setOutputs(outputs2);
		
		saveOrUpdate(backActionTest2);
		saveOrUpdate(backActionTest1);

		TestScope customScope = createEntityInstance(TestScope.class);
		customScope.setUserName("demo");
		customScope.setScopeId("Custom");
		saveOrUpdate(customScope);
		
		TestEntitySerializer.serializeToStore(dakarLondre, customScope, false, false, getBackendController());

	}
}
